/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_components/zhiqim_manager.htm
 *
 * Zhiqim Manager is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.manager.dao;

import java.sql.SQLException;
import java.util.LinkedHashMap;
import java.util.List;

import org.zhiqim.kernel.annotation.AnAlias;
import org.zhiqim.kernel.config.ItemType;
import org.zhiqim.kernel.constants.SignConstants;
import org.zhiqim.kernel.util.Ints;
import org.zhiqim.kernel.util.Longs;
import org.zhiqim.kernel.util.Validates;
import org.zhiqim.manager.ZmrConstants;
import org.zhiqim.manager.dbo.ZmrParam;
import org.zhiqim.orm.ORM;
import org.zhiqim.orm.ORMException;
import org.zhiqim.orm.ORMServer;
import org.zhiqim.orm.dbo.Selector;
import org.zhiqim.orm.dbo.Updater;

/**
 * 参数访问对象
 *
 * @version v1.0.0 @author zouzhigang 2015-5-28 新建与整理
 * @version v1.4.1 @author zouzhigang 2018-5-3 由ZmrParamCache改为ZmrParamDao
 */
@AnAlias("ZmrParamDao")
public class ZmrParamDao implements ZmrConstants, SignConstants
{
    /*************************************************************************************************/
    //默认为第一个数据库初始化参数
    /*************************************************************************************************/
    
    /** 检查数据不存在时新建参数对象，默认值和验证为空，允许修改 */
    public static void addParamIfNotExists(String paramGroup, String paramKey, int paramSeq, String paramDesc) throws Exception
    {
        addParamIfNotExists(paramGroup, paramKey, null, paramSeq, ItemType.PUBLIC, null, paramDesc);
    }
    
    /** 检查数据不存在时新建参数对象，默认验证为空 */
    public static void addParamIfNotExists(String paramGroup, String paramKey, String paramValue, int paramSeq, ItemType paramType, String paramDesc) throws Exception
    {
        addParamIfNotExists(paramGroup, paramKey, paramValue, paramSeq, paramType, null, paramDesc);
    }
    
    /** 检查数据不存在时新建参数对象，全7个字段 */
    public static void addParamIfNotExists(String paramGroup, String paramKey, String paramValue, int paramSeq, ItemType paramType, String paramValidate, String paramDesc) throws Exception
    {
        if (ORM.table().count(ZmrParam.class, paramGroup, paramKey) == 0)
        {
            replaceParam(paramGroup, paramKey, paramValue, paramSeq, paramType, paramValidate, paramDesc);
        }
    }
    
    /** 新建或替换参数对象，默认验证为空 */
    public static void replaceParam(String paramGroup, String paramKey, String paramValue, int paramSeq, ItemType paramType, String paramDesc) throws Exception
    {
        replaceParam(paramGroup, paramKey, paramValue, paramSeq, paramType, null, paramDesc);
    }
    
    /** 新建或替换参数对象，全7个字段 */
    public static void replaceParam(String paramGroup, String paramKey, String paramValue, int paramSeq, ItemType paramType, String paramValidate, String paramDesc) throws Exception
    {
        ZmrParam param = new ZmrParam();
        param.setParamGroup(paramGroup);
        param.setParamKey(paramKey);
        param.setParamValue(paramValue);
        param.setParamSeq(paramSeq);
        param.setParamType(ItemType.toString(paramType));
        param.setParamValidate(paramValidate);
        param.setParamDesc(paramDesc);

        ORM.table().replace(param);
    }
    
    /*************************************************************************************************/
    //默认为第一个数据库配置的获取参数方法
    /*************************************************************************************************/
    
    /** 判断是否存在参数组 */
    public static boolean hasGroup(String paramGroup) throws ORMException, SQLException
    {
        return ORM.table().count(ZmrParam.class, new Selector("paramGroup", paramGroup)) > 0;
    }
    
    /** 判断是否存在参数 */
    public static boolean hasParam(String paramGroup, String paramKey) throws ORMException, SQLException
    {
        return ORM.table().count(ZmrParam.class, paramGroup, paramKey) > 0;
    }
    
    /** 获取参数组表 */
    public static LinkedHashMap<String, LinkedHashMap<String, ZmrParam>> getGroupMap() throws ORMException, SQLException
    {
        LinkedHashMap<String, LinkedHashMap<String, ZmrParam>> groupMap = new LinkedHashMap<>();
        
        List<ZmrParam> paramList = ORM.table().list(ZmrParam.class, new Selector().addMustNotEqual("paramType", "private").addOrderbyAsc("paramGroup,paramSeq"));
        for (ZmrParam param : paramList)
        {
            LinkedHashMap<String, ZmrParam> paramMap = groupMap.get(param.getParamGroup());
            if (paramMap == null)
            {
                paramMap = new LinkedHashMap<String, ZmrParam>();
                groupMap.put(param.getParamGroup(), paramMap);
            }
            
            paramMap.put(param.getParamKey(), param);
        }
        return groupMap;
    }
    
    /** 获取参数（获取缓存拷贝数据） */
    public static ZmrParam getParam(String paramGroup, String paramKey) throws ORMException, SQLException
    {
        return ORM.table().item(ZmrParam.class, paramGroup, paramKey);
    }
    
    /** 获取参数（获取缓存原始数据） */
    public static ZmrParam getParamCacheRaw(String paramGroup, String paramKey) throws ORMException, SQLException
    {
        return ORM.table().cacheItemRaw(ZmrParam.class, paramGroup, paramKey);
    }
    
    /** 获取字符串数据（如果有缓存，取原始缓存，否则取数据库） */
    public static String getString(String paramGroup, String paramKey) throws ORMException, SQLException
    {
        ORMServer server = ORM.server();
        
        ZmrParam param = null;
        if (server.isCache(ZmrParam.class))
            param = server.table().cacheItemRaw(ZmrParam.class, paramGroup, paramKey);
        else
            param = server.table().item(ZmrParam.class, paramGroup, paramKey);
        
        return (param == null)?null:param.getParamValue();
    }
    
    /** 获取字符串数据，为null取缺省值 */
    public static String getString(String paramGroup, String paramKey, String defaultValue) throws ORMException, SQLException
    {
        String value = getString(paramGroup, paramKey);
        return (Validates.isEmptyBlank(value))?defaultValue:value;
    }
    
    /** 获取整型数据 */
    public static int getInt(String paramGroup, String paramKey) throws ORMException, SQLException
    {
        return getInt(paramGroup, paramKey, -1);
    }
    
    /** 获取整型数据，为null取缺省值 */
    public static int getInt(String paramGroup, String paramKey, int defaultValue) throws ORMException, SQLException
    {
        return Ints.toInt(getString(paramGroup, paramKey), defaultValue);
    }
    
    /** 获取长整型数据 */
    public static long getLong(String paramGroup, String paramKey) throws ORMException, SQLException
    {
        return getLong(paramGroup, paramKey, -1);
    }
    
    /** 获取整型数据，为null取缺省值 */
    public static long getLong(String paramGroup, String paramKey, int defaultValue) throws ORMException, SQLException
    {
        return Longs.toLong(getString(paramGroup, paramKey), defaultValue);
    }
    
    /** 判断是否为真 */
    public static boolean isTrue(String paramGroup, String paramKey) throws ORMException, SQLException
    {
        return _TRUE_.equals(getString(paramGroup, paramKey));
    }
    
    /** 判断是否为真，为null取缺省值 */
    public static boolean isTrue(String paramGroup, String paramKey, String defaultValue) throws ORMException, SQLException
    {
        return _TRUE_.equals(getString(paramGroup, paramKey, defaultValue));
    }

    /*************************************************************************************************/
    //默认为第一个数据库配置的更新和刷新参数
    /*************************************************************************************************/
    
    /** 更新缓存值 */
    public static boolean doUpdate(String paramGroup, String paramKey, int paramValue) throws ORMException, SQLException
    {
        return doUpdate(paramGroup, paramKey, String.valueOf(paramValue));
    }
    
    /** 更新缓存值 */
    public static boolean doUpdate(String paramGroup, String paramKey, long paramValue) throws ORMException, SQLException
    {
        return doUpdate(paramGroup, paramKey, String.valueOf(paramValue));
    }
    
    /** 更新缓存值 */
    public static boolean doUpdate(String paramGroup, String paramKey, boolean paramValue) throws ORMException, SQLException
    {
        return doUpdate(paramGroup, paramKey, String.valueOf(paramValue));
    }
    
    /** 更新缓存值 */
    public static boolean doUpdate(String paramGroup, String paramKey, String paramValue) throws ORMException, SQLException
    {
        //更新到数据库
        Updater updater = new Updater();
        updater.addMust("paramGroup", paramGroup);
        updater.addMust("paramKey", paramKey);
        updater.addField("paramValue", paramValue);
        return ORM.table().update(ZmrParam.class, updater) > 0;
    }
    
    /*************************************************************************************************/
    //以下为ZMR本身自带的六项参数
    /*************************************************************************************************/
    
    /** 获取首页主题风格 */
    public static String getThemeIndex() throws ORMException, SQLException
    {
        return getString(ZMR_NAME, ZMR_THEME_INDEX, ZMR_THEME_00_DEFAULT);
    }
    
    /** 更新首页主题风格 */
    public static void doUpdateThemeIndex(String theme) throws ORMException, SQLException
    {
        doUpdate(ZMR_NAME, ZMR_THEME_INDEX, theme);
    }
    
    /** 获取主页主题风格 */
    public static String getThemeMain() throws ORMException, SQLException
    {
        return getString(ZMR_NAME, ZMR_THEME_MAIN, ZMR_THEME_00_DEFAULT);
    }
    
    /** 更新主页主题风格 */
    public static void doUpdateThemeMain(String theme) throws ORMException, SQLException
    {
        doUpdate(ZMR_NAME, ZMR_THEME_MAIN, theme);
    }
    
    public static boolean isThemeFrame() throws ORMException, SQLException
    {
        return isTrue(ZMR_NAME, ZMR_THEME_FRAME, _FALSE_);
    }
    
    /** 是否有管理登录页 */
    public static boolean hasManageLogin() throws ORMException, SQLException
    {
        return isTrue(ZMR_NAME, ZMR_HAS_MANAGE_LOGIN);
    }
    
    /** 是否有验证码 */
    public static boolean hasVerificationCode() throws ORMException, SQLException
    {
        return isTrue(ZMR_NAME, ZMR_HAS_VERIFICATION_CODE);
    }
    
    /** 是否记住用户名 */
    public static boolean hasRememberCode() throws ORMException, SQLException
    {
        return isTrue(ZMR_NAME, ZMR_HAS_REMEMBER_CODE);
    }
    
    /** 更新记住用户名 */
    public static void doUpdateRememberCode(boolean value) throws ORMException, SQLException
    {
        doUpdate(ZMR_NAME, ZMR_HAS_REMEMBER_CODE, value?_TRUE_:_FALSE_);
    }
    
    /** 是否记住密码 */
    public static boolean hasRememberPass() throws ORMException, SQLException
    {
        return isTrue(ZMR_NAME, ZMR_HAS_REMEMBER_PASS);
    }
    
    /** 获取主页地址 */
    public static String getMainUrl() throws ORMException, SQLException
    {
        return getString(ZMR_NAME, ZMR_MAIN_URL, ZMR_MAIN_URL_DEFAULT);
    }
    
    /** 获取主页首页地址 */
    public static String getMainIndexUrl() throws ORMException, SQLException
    {
        return isThemeFrame()?ZMR_MAIN_URL_WELCOME:ZMR_MAIN_URL_DEFAULT;
    }

    /** 获取保留操作日志天数 */
    public static int getRemainLogDay() throws ORMException, SQLException
    {
        return getInt(ZMR_NAME, ZMR_REMAIN_LOG_DAY, 7);
    }
    
    /** 是否使用CDN路径 */
    public static boolean hasCdnPath() throws ORMException, SQLException
    {
        return !Validates.isEmptyBlank(getString(ZMR_NAME, ZMR_CDN_PATH));
    }
    
    /** 获取CDN路径 */
    public static String getCdnPath() throws ORMException, SQLException
    {
        return getString(ZMR_NAME, ZMR_CDN_PATH);
    }
    
    /** 获取公钥 */
    public static String getPublicKey() throws ORMException, SQLException
    {
        return getString(ZMR_NAME, ZMR_PUBLIC_KEY);
    }
    
    /** 获取私钥 */
    public static String getPrivateKey() throws ORMException, SQLException
    {
        return getString(ZMR_NAME, ZMR_PRIVATE_KEY);
    }
    
    /** 是否取操作员继承的所有部门权限 */
    public static boolean isOperatorDeptAllRule() throws ORMException, SQLException
    {
        return isTrue(ZMR_NAME, ZMR_OPERATOR_DEPT_ALL_RULE);
    }
}